package top.ochiamalu.aioj.controller;

import cn.hutool.core.lang.UUID;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import top.ochiamalu.aioj.common.BaseResponse;
import top.ochiamalu.aioj.common.ErrorCode;
import top.ochiamalu.aioj.disruptor.JudgeEventProducer;
import top.ochiamalu.aioj.domain.dto.judge.JudgeDTO;
import top.ochiamalu.aioj.domain.dto.judge.TestCodeDTO;
import top.ochiamalu.aioj.domain.vo.judge.ExecuteCodeVO;
import top.ochiamalu.aioj.domain.vo.judge.SubmitHistoryVO;
import top.ochiamalu.aioj.domain.vo.judge.SubmitVO;
import top.ochiamalu.aioj.domain.vo.judge.TestCodeVO;
import top.ochiamalu.aioj.service.JudgeService;
import top.ochiamalu.aioj.util.ResultUtils;

import javax.annotation.Resource;

/**
 * 判题控制器
 *
 * @author ochiamalu
 * @date 2025/01/23
 */
@RestController
@RequestMapping("/judges")
public class JudgeController {

    @Resource
    private JudgeService judgeService;

    @Resource
    private JudgeEventProducer producer;


    /**
     * 执行代码
     *
     * @param judgeDTO 执行代码dto
     * @return {@link BaseResponse }<{@link SubmitVO }>
     */
    @PostMapping("/judge")
    public BaseResponse<SubmitVO> judge(@RequestBody JudgeDTO judgeDTO) {
        // 生成提交ID
        String submissionId = UUID.fastUUID().toString(true);
        judgeDTO.setSubmissionId(submissionId);
        SubmitVO submitVO = judgeService.getSubmitInfo(judgeDTO, submissionId);

        // 发布到Disruptor
        producer.publishEvent(judgeDTO);
        return ResultUtils.success(submitVO);
    }

    /**
     * 获得评判结果
     *
     * @param submissionId 提交id
     * @return {@link BaseResponse }<{@link ExecuteCodeVO }>
     */
    @GetMapping("/result/{submissionId}")
    public BaseResponse<ExecuteCodeVO> getJudgeResult(@PathVariable String submissionId) {
        ExecuteCodeVO result = judgeService.getJudgeResult(submissionId);
        return ResultUtils.success(result);
    }

    /**
     * 得到上一次判题结果
     *
     * @return {@link BaseResponse }<{@link ExecuteCodeVO }>
     */
    @GetMapping("/last/{questionId}")
    public BaseResponse<ExecuteCodeVO> getLastJudgeResult(@PathVariable Long questionId) {
        ExecuteCodeVO result = judgeService.getLastJudgeResult(questionId);
        if (result == null) {
            return ResultUtils.error(ErrorCode.PARAMS_ERROR);
        }
        return ResultUtils.success(result);
    }

    /**
     * 具有最后判题结果
     *
     * @param questionId 题目ID
     * @return {@link BaseResponse }<{@link Boolean }>
     */
    @GetMapping("/hasLast/{questionId}")
    public BaseResponse<Boolean> hasLastJudgeResult(@PathVariable Long questionId) {
        boolean result = judgeService.hasLastJudgeResult(questionId);
        return ResultUtils.success(result);
    }

    /**
     * 获取等待人数
     *
     * @return {@link BaseResponse }<{@link Integer }>
     */
    @GetMapping("/waiting")
    public BaseResponse<Integer> getWaitingCount() {
        int waitingCount = producer.getWaitingCount();
        return ResultUtils.success(waitingCount);
    }

    /**
     * 测试代码
     *
     * @param testCodeDTO 测试代码dto
     * @return {@link BaseResponse }<{@link TestCodeVO }>
     */
    @PostMapping("/test")
    public BaseResponse<TestCodeVO> testCode(@RequestBody TestCodeDTO testCodeDTO) {
        TestCodeVO testCodeVO = judgeService.testCode(testCodeDTO);
        return ResultUtils.success(testCodeVO);
    }

    /**
     * 获取提交历史记录
     *
     * @param account 账户
     * @return {@link BaseResponse }<{@link SubmitHistoryVO }>
     */
    @GetMapping("/history/submit/{account}")
    public BaseResponse<SubmitHistoryVO> getSubmitHistory(@PathVariable String account) {
        SubmitHistoryVO submitVO = judgeService.getSubmitHistory(account);
        return ResultUtils.success(submitVO);
    }
}
